﻿using System;
using System.Web.Security;
using System.Web;
using System.Linq;
using PB.CustomRoleProvider;
using System.Collections.Generic;

namespace PB.FBConnect
{
    public class FBMembership
    {

        public static bool LogonUser(facebook.Schema.user fbsUser)
        {
            bool success = false;
            bool firstTimeFlag = false;
            if (fbsUser != null && fbsUser.uid > 0)
            {
                FBUser fbUser = (FBUser)Membership.GetUser(fbsUser.uid.ToString());
                if (fbUser == null)
                {
                    CustomIdentity cUser = new CustomIdentity(fbsUser.uid.Value, fbsUser.name, fbsUser.pic, false, DateTime.Now);
                    RegisterUser(cUser);
                    fbUser = new FBUser(cUser, fbsUser);
                    firstTimeFlag = true;

                }
                else
                {
                    SyncFBAndCustomUser(fbUser);
                }
                if (fbUser.CustomUser.IsLocked == false)
                {
                    WriteAuthCookies(fbsUser.uid.ToString(), fbsUser.name, firstTimeFlag);
                    success = true;
                }
                
            }
            else
            {
                throw new Exception("System could not logon. User object cannot be null.");
            }
            return success;
        }

        private static void SyncFBAndCustomUser(FBUser fbUser)
        {
            if (fbUser.CustomUser != null && fbUser.FacebookUser != null)
            {
                bool isDirty = false;
                if (fbUser.CustomUser.DisplayName != fbUser.FacebookUser.name)
                {
                    fbUser.CustomUser.DisplayName = fbUser.FacebookUser.name;
                    isDirty = true;
                }
                if (fbUser.CustomUser.Picture != fbUser.FacebookUser.pic)
                {
                    fbUser.CustomUser.Picture = fbUser.FacebookUser.pic;
                    isDirty = true;
                }
                if (isDirty == true)
                {
                    UpdateUser(fbUser.CustomUser);
                }
            }
        }

        private static void RegisterUser(CustomIdentity cUser)
        {
            DBMapper.RegisterMember(cUser);
            Roles.AddUserToRole(cUser.FacebookUserId.ToString(), "Members");            
        }
        
        public static FBUser GetFBUser(long fbUserId)
        {
            FBUser fbUser = null;
            if (fbUserId > 0)
            {
                CustomIdentity cUser  = DBMapper.GetCustomIdentityFromDB(fbUserId);
                facebook.Schema.user sUser = FBHelper.GetFBSchemaUser(fbUserId);
                if (cUser != null && sUser != null)
                {
                    fbUser = new FBUser(cUser, sUser);
                }
            }
            return fbUser;
        }

        public static bool IsUserRegistered(long fbUserId)
        {
            FBUser user = (FBUser)Membership.GetUser(fbUserId.ToString());
            if (user != null)
                return true;
            else
                return false;

        }

        public static List<FBUser> GetAllUsers()
        {
            int totalRecords = 0;
            List<FBUser> returnList = GetAllFBUsersList(0, int.MaxValue, out totalRecords);            
            return returnList;
        }


        private static void WriteAuthCookies(string username, string displayname, bool firstTimeFlag)
        {
            if (Membership.ValidateUser(username, null))
            {
                if (HttpContext.Current != null)
                {
                    HttpCookie FBDisplayNameCookie = new HttpCookie("FBDisplayName");
                    FBDisplayNameCookie.Value = displayname;
                    HttpContext.Current.Response.Cookies.Add(FBDisplayNameCookie);
                    if (firstTimeFlag)
                    {
                        HttpContext.Current.Response.Cookies.Add(new HttpCookie("newuserflag", "true"));
                    }
                }
                FormsAuthentication.RedirectFromLoginPage(username, false);
            }
        }

        internal static bool UpdateUser(CustomIdentity cUser)
        {
            return DBMapper.UpdateUser(cUser);
        }

        internal static bool UnlockUser(long fbUserId)
        {
            FBUser fbUser = GetFBUser(fbUserId);
            if (fbUser != null)
            {
                if (fbUser.CustomUser.IsLocked == true)
                {
                    fbUser.CustomUser.IsLocked = false;
                    return UpdateUser(fbUser.CustomUser);
                }
            }
            return false;
        }

       
        internal static bool LockUser(long fbUserId)
        {
            FBUser fbUser = GetFBUser(fbUserId);
            if (fbUser != null)
            {
                if (fbUser.CustomUser.IsLocked == false)
                {
                    fbUser.CustomUser.IsLocked = true;
                    return UpdateUser(fbUser.CustomUser);
                }
            }
            return false;
        }


        internal static List<FBUser> GetAllFBUsersList(int pageIndex, int pageSize, out int totalRecords)
        {
            List<FBUser> returnList = new List<FBUser>();

            List<CustomIdentity> cUsersList = DBMapper.GetAllUsers(pageIndex, pageSize, out totalRecords);

            List<long> uids = (from u in cUsersList select u.FacebookUserId).ToList<long>();


            FConnectAPI fbApi = new FConnectAPI(true, true);
            var schemaUsers = fbApi.users.getInfo(uids) ;

            if (cUsersList != null && schemaUsers != null && cUsersList.Count == schemaUsers.Count)
            {
                for (int i = 0; i < cUsersList.Count; i++)
                {
                    if (cUsersList[i] != null && schemaUsers[i] != null && cUsersList[i].FacebookUserId == schemaUsers[i].uid.Value)
                    {
                        FBUser fbUser = new FBUser(cUsersList[i], schemaUsers[i]);
                        returnList.Add(fbUser);
                    }

                }
            }

            totalRecords = returnList.Count;
            return returnList;
        }

        internal static MembershipUserCollection GetAllUsersCollection(int pageIndex, int pageSize, out int totalRecords)
        {
            List<FBUser> allUsersList = GetAllFBUsersList(pageIndex, pageSize, out totalRecords);
            MembershipUserCollection coll = new MembershipUserCollection();
            if (allUsersList != null && allUsersList.Count > 0)
            {
                foreach (FBUser user in allUsersList)
                    coll.Add(user);
            }
            totalRecords = coll.Count;
            return coll;                       
        }
    }
}
